package com.warrior.gatherweb.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.warrior.gatherweb.dto.GatherDataPageDto;
import com.warrior.gatherweb.exceptionhandler.ApplicationException;
import com.warrior.gatherweb.service.GatherDataService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * @ClassName com.warrior.gatherweb.service.impl.GatherDataServiceImpl.java
 * @Author xujian
 * @Description
 * @CreateTime 2021年01月05日 10:59:00
 */
@Slf4j
@Service
public class GatherDataServiceImpl implements GatherDataService {

    @Autowired
    private ElasticsearchRestTemplate esRestTemplate;

    @Value("${spring.elasticsearch.gather-index}")
    private String gatherIndex;

    @Override
    public JSONArray getGatherDataByPage(GatherDataPageDto params) throws ApplicationException {
        if (params.getPageNum() <= 0 || params.getPageSize() <= 0) {
            throw new ApplicationException(ResultCode.FAIL_CODE, "pageNum,pageSize不能小于0");
        }
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = PageRequest.of(params.getPageNum() - 1, params.getPageSize(), sort);
        BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(queryBuilder);
        nativeSearchQuery.addIndices(gatherIndex);
        nativeSearchQuery.setPageable(pageRequest);
        QueryBuilder timeBuilder = initTimestampQuery(params.getStartTime(), params.getEndTime());
        if (null != timeBuilder) {
            queryBuilder.must(timeBuilder);
        }
        if (!StringUtils.isEmpty(params.getMetricType())) {
            queryBuilder.must(QueryBuilders.termsQuery("metricType", params.getMetricType()));
        }
        return esRestTemplate.query(nativeSearchQuery, response -> {
            SearchHit[] hits = response.getHits().getHits();
            JSONArray result = new JSONArray();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                JSONObject jsonObject = JSONObject.parseObject(sourceAsString);
                result.add(jsonObject);
            }
            return result;
        });
    }

    private QueryBuilder initTimestampQuery(String startTime, String endTime) {
        QueryBuilder timestampQuery = null;
        String format = CommonStatus.CONSTANT_DATETIME_FORMAT;
        if ((!StringUtils.isEmpty(startTime) && startTime.length() > 10) || (!StringUtils.isEmpty(endTime) && endTime.length() > 10)) {
            format = CommonStatus.CONSTANT_DATETIME_FORMAT;
        }
        if (!StringUtils.isEmpty(startTime)) {
            timestampQuery = QueryBuilders.rangeQuery("createTime")
                    .format(format)
                    .gte(startTime);
        }
        if (!StringUtils.isEmpty(endTime)) {
            if (null == timestampQuery) {
                timestampQuery = QueryBuilders.rangeQuery("createTime")
                        .format(format)
                        .lte(endTime);
            } else {
                timestampQuery = QueryBuilders.rangeQuery("createTime")
                        .format(format)
                        .gte(startTime)
                        .lte(endTime);
            }
        }
        return timestampQuery;
    }

}
